/**
 * Copyright 2007 Christian Mueller
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 
 * use this file except in compliance with the License. You may obtain a copy of 
 * the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by 
 * applicable law or agreed to in writing, software distributed under the License 
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
 * either express or implied. See the License for the specific language governing 
 * permissions and limitations under the License.
 * 
 * Description:
 * Defines how a agent will be executed
 */

#include "myglobal.h"
#include "globopts.h"
#include "execute_agent.h"
#include <nif.h>
#include <agents.h>
/**
 * This function will be start by the main routine
 * lets check the parameters and start the agent if everything is ok
 **/
void run_execute_agent()
{
	LOG_DEBUG1("void run_execute_agent() - start");
	
	/** Check Database **/
	LOG_DEBUG2("check database entry");
	if (opt_database[0]=='\0') {
		LOG_ERROR("Please define the database with option --database <string>");
		return;	
	}
	execute_agent(opt_executeAgent, opt_database);
	LOG_DEBUG1("void run_execute_agent() - end");
}

void execute_agent(const char *agentname, const char *databasename)
{
	LOG_DEBUG1("void execute_agent(const char *agentname, const char *databasename) - start");
	if (HAS_DEBUG2) {
		char debug_string[256];
		sprintf(debug_string,"agentname = %s\n",agentname);
		LOG_DEBUG2(debug_string);
		sprintf(debug_string,"databasename = %s\n",databasename);
		LOG_DEBUG2(debug_string);
	}
	
	// Open the database
	LOG_DEBUG2("Trying to open the database....");
	LOG_DEBUG3("call NSFDbOpen (path_name, &db_handle)");
	DBHANDLE    db_handle;
	if (NSFDbOpen (databasename, &db_handle)) {
		LOG_ERROR("The defined database couldn't be opend!");
		return;
	}	
	
	NOTEID AgentID;
	// Try to get the agent from private
	// and if not found from shard
	LOG_DEBUG3("call NIFFindPrivateDesignNote (db_handle, agentname, NOTE_CLASS_FILTER, &AgentID)");
	if (NIFFindPrivateDesignNote (db_handle, agentname, NOTE_CLASS_FILTER, &AgentID)) {
		LOG_DEBUG4("Not found as private agent... try to find the shared one!");
		// get the agent from shared
		LOG_DEBUG3("call NIFFindDesignNote (db_handle, agentname, NOTE_CLASS_FILTER, &AgentID)");
		if (NIFFindDesignNote (db_handle, agentname, NOTE_CLASS_FILTER, &AgentID)) {
			LOG_ERROR("The defined agent couldn't be found!");
			LOG_DEBUG3("call NSFDbClose (db_handle)");
			NSFDbClose (db_handle);
			return;
		}
	}
	
	LOG_DEBUG2("Agent was found....!");
	// now we have the agent
	// Tryp to open
	HAGENT  hOpenAgent;
	LOG_DEBUG3("call AgentOpen (db_handle, AgentId, &hOpenAgent)");
	if (AgentOpen (db_handle, AgentID, &hOpenAgent)) {
		LOG_ERROR("The defined agent couldn't be opend!");
		LOG_DEBUG3("call NSFDbClose (db_handle)");
		NSFDbClose (db_handle);
		return;
	}
	
	
	HAGENTCTX  hOpenAgentCtx;
	LOG_DEBUG3("call AgentCreateRunContext (hOpenAgent, NULL, (DWORD) 0, &hOpenAgentCtx)");
	if (AgentCreateRunContext (hOpenAgent, NULL, (DWORD) 0, &hOpenAgentCtx)) {
		LOG_ERROR("Couldn't create the agent context!");
		LOG_DEBUG3("call AgentClose (hOpenAgent)");
		AgentClose (hOpenAgent);
		LOG_DEBUG3("call NSFDbClose (db_handle)");
		NSFDbClose (db_handle);
		return;
	}
	
	LOG_INFO("Starting the agent.");
	LOG_DEBUG3("call AgentRun (hOpenAgent, hOpenAgentCtx, (HANDLE) 0, (DWORD) 0)");
	if (AgentRun (hOpenAgent, hOpenAgentCtx, (HANDLE) 0, (DWORD) 0)) {
		LOG_ERROR("Execution of agent failed!");
		LOG_DEBUG3("call AgentDestroyRunContext (hOpenAgentCtx)");
		AgentDestroyRunContext (hOpenAgentCtx);	
		LOG_DEBUG3("call AgentClose (hOpenAgent)");
		AgentClose (hOpenAgent);
		LOG_DEBUG3("call NSFDbClose (db_handle)");
		NSFDbClose (db_handle);
		return;
	}
	LOG_INFO("Execution of agent finished.");
	
	// Closing context
	LOG_DEBUG3("call AgentDestroyRunContext (hOpenAgentCtx)");
	AgentDestroyRunContext (hOpenAgentCtx);	
	
	// Closing agent
	LOG_DEBUG3("call AgentClose (hOpenAgent)");
	AgentClose (hOpenAgent);
	
	
	// Closing database
	LOG_DEBUG3("call NSFDbClose (db_handle)");
	if (NSFDbClose (db_handle))
   	{
       LOG_ERROR("The database handle couldn't be closed!");
       return;
   	}
	
	
	
	
	LOG_DEBUG1("void execute_agent(const char *agentname, const char *databasename) - end");
}

